﻿using SuperKit.Executor;
using System;
using System.Collections.Generic;
using System.Text;

namespace SuperKit {
  public class ArgReader {
    public string[] Args { get; set; }

    public static ArgReader InitialArgs { get; set; }
    public DirectoryExecutorItem Owner { get; set; }

    /**********************************************************************
     * 参数
     *********************************************************************/
    public bool IsCommand => IsContain("-command");
    public bool IsZip => IsContain("-zip");
    public int TypeId => GetInteger("-t");
    public bool IsClose => IsContain("-close");
    public string Directory => GetDirectory();
    public string FileName => GetParameter("-f");
    public bool IsIgnoreExist => IsContain("-ignore");
    public bool IsTest => IsContain("-test");
    public bool IsTempDir => IsContain("-tempDir");
    public bool IsShell => IsContain("-shell");
    public int ShellIndex => GetInteger("-shell_idx");
    public int MaxWidth => GetInteger("-maxWidth", ConfigReader.Instance.GetInt("MaxWidth", 1920));
    public int MaxHeight => GetInteger("-maxHeight", ConfigReader.Instance.GetInt("MaxHeight", 1920));
    public int Width => GetInteger("-width");
    public int Height => GetInteger("-height");
    public string Output => GetParameter("-o");
    public bool IsClearEmpty => IsContain("-clearempty");
    public bool IsCurrentDir => IsContain("-currentDir");
    public string OriginText { get; }
    public string TargetDir => GetParameter("-dir");

    /**********************************************************************
     * 特殊处理参数
     *********************************************************************/
    private string _defaultDirectory;

    public ArgReader(string[] fullArgs) {
      SetArgs(fullArgs);
    }

    public ArgReader(string text, string dir) {
      this.OriginText = text;
      SetArgs(text, dir);
    }

    public void SetDefaultDirectory(string value) {
      _defaultDirectory = value;
    }

    public string GetDirectory() {
      var dir = GetParameter("-d");
      if (Kit.IsEmpty(dir)) {
        return _defaultDirectory;
      } else {
        return dir;
      }
    }

    public void Execute(IExecutorOwner form) {
      //PrintArgs(form);

      if (IsContain("-pdf")) {
        ExecuteCommand("图片转PDF", new SpireConverter(this, form, Directory));
      } else if (IsContain("-ntod")) {
        ExecuteCommand("由文件创建目录", new NameToDirectory(this, form, FileName));
      } else if (IsContain("-renp")) {
        ExecuteCommand("修改父级目录名", new RenameParentDateBrand(this, form, FileName));
      } else if (IsContain("-zipd")) {
        ExecuteCommand("打包子级目录", new ZipPackDirectory(this, form, Directory));
      } else if (IsContain("-fastren")) {
        ExecuteCommand("快速名称修正", new FastRename(this, form, Directory));
      } else if (IsContain("-countimg")) {
        ExecuteCommand("目录改名", new ImageCounter(this, form, Directory));
      } else if (IsContain("-unzip")) {
        ExecuteCommand("解压全部", new UnzipAll(this, form, Directory));
      } else if (IsContain("-cbuilder")) {
        ExecuteCommand("目录合集整理", new CollectionBuilder(this, form, Directory));
      } else if (IsContain("-fcollect")) {
        ExecuteCommand("文件查找整理", new FileCollector(this, form, Directory));
      } else if (IsContain("-dirup")) {
        ExecuteCommand("目录提升一级", new DirCollector(this, form, Directory));
      } else if (IsContain("-dirname")) {
        ExecuteCommand("收集目录名称", new CollectDirName(this, form, Directory));
      } else if (IsContain("-combinemv")) {
        ExecuteCommand("合并目录电影", new CombineMovie(this, form, Directory));
      } else if (IsContain("-pdfclear")) {
        ExecuteCommand("清除指定PDF图像", new PDFClear(this, form, Directory));
      } else if (IsContain("-unzippdf")) {
        ExecuteCommand("解压PDF", new UnzipPDF(this, form, Directory));
      } else if (IsContain("-combinepdf")) {
        ExecuteCommand("合并PDF", new CombinePDF(this, form, Directory));
      } else if (IsContain("-compareImage")) {
        ExecuteCommand("比较图片", new ImageCompare(this, form, Directory));
      } else if (IsContain("-divideCatalog")) {
        ExecuteCommand("分离文件目录", new DivideCatalog(this, form, Directory));
      } else if (IsContain("-tohtml")) {
        ExecuteCommand("文本转HTML", new HtmlConverter(this, form, Directory));
      } else if (IsContain("-clearFileName")) {
        ExecuteCommand("清除文件名字符串", new ClearFileName(this, form, Directory));
      } else if (IsContain("-autoResize")) {
        ExecuteCommand("自动调整文件大小", new AutoResize(this, form, Directory));
      } else if (IsContain("-countpdf")) {
        ExecuteCommand("PDF页数统计", new PDFPageCounter(this, form, Directory));
      } else if (IsContain("-pdfshrink")) {
        ExecuteCommand("PDF瘦身", new PDFShrink(this, form, Directory));
      } else if (IsContain("-splitFileToDir")) {
        ExecuteCommand("按名字分类文件", new SplitFileToDirectory(this, form, Directory));
      } else if (IsContain("-splitFilePage")) {
        ExecuteCommand("按数量分类文件", new SplitFilePage(this, form, Directory));
      } else if (IsContain("-splitDirPage")) {
        ExecuteCommand("按数量分类目录", new SplitDirPage(this, form, Directory));
      } else if (IsContain("-numberize")) {
        ExecuteCommand("全文件序号化", new FullNumberize(this, form, Directory));
      } else if (IsContain("-safeRename")) {
        ExecuteCommand("安全移除(替换)文件名", new SafeRename(this, form, Directory));
      } else if (IsContain("-addDir")) {
        ExecuteCommand("增加目录", new AddDirectory(this, form, Directory));
      } else if (IsContain("-mixCombineMoive")) {
        ExecuteCommand("分割拼接视频(混剪)", new MixCombineMovie(this, form, Directory));
      } else if (IsContain("-makeVideo")) {
        ExecuteCommand("压缩视频", new MakeVideo(this, form, Directory));
      } else if (IsContain("-clearEmptyDir")) {
        ExecuteCommand("清除空目录", new ClearEmptyDirectory(this, form, Directory));
      } else if (IsContain("-addFavor")) {
        ExecuteCommand("增加星标", new AddFavorMark(this, form, Directory));
      } else if (IsContain("-safeMv")) {
        ExecuteCommand("安全化视频", new SafelizeMovie(this, form, Directory));
      } else if (IsContain("-zipeach")) {
        ExecuteCommand("压缩每一个子项", new ZipEach(this, form, Directory));
      } else if (IsContain("-bili")) {
        ExecuteCommand("处理Bilibili下载", new BilibiliMovie(this, form, Directory));
      } else if (IsContain("-countvideo")) {
        ExecuteCommand("统计视频信息", new CountVideo(this, form, Directory));
      } else if (IsContain("-bindsrt")) {
        ExecuteCommand("合并字幕", new BindSrt(this, form, Directory));
      } else if (IsContain("-splittext")) {
        ExecuteCommand("分割txt文件", new SplitText(this, form, Directory));
      } else if (IsContain("-fastpack")) {
        ExecuteCommand("快速打包", new FastPackExe(this, form, Directory));
      } else if (IsContain("-fastunpack")) {
        ExecuteCommand("快速解包", new FastUnpackExe(this, form, Directory));
      } else if (IsContain("-fastpackupdate")) {
        ExecuteCommand("更新包到数据库", new FastPackUpdate(this, form, Directory));
      } else if (IsContain("-python")) {
        ExecuteCommand("运行Python", new RunPython(this, form, Directory));
      } else {
        form.Flush("没有指定执行的命令！");
      }

      if (OriginText != null && OriginText.Length > 0) {
        ConfigReader.Instance.LastArgs = OriginText;
        ConfigReader.Instance.Save();
      }
    }

    private void PrintArgs(IExecutorOwner form) {
      for (int i = 0; i < Args.Length; i++) {
        form.Flush($"Arg{i}:{Args[i]}");
      }
    }

    private void ExecuteCommand(string cmd, CommandExecutor exe) {
      exe.Owner = Owner;
      exe.Flush(string.Format("---- {0} ----", cmd));
      exe.Flush(exe.FilePath);
      exe.Execute();
    }

    public void SetArgs(string text, string dir) {

      var args = Analysis(text);
      var dirString = new string[] { "-d", dir };
      Args = new string[args.Length + dirString.Length];
      args.CopyTo(Args, 0);
      dirString.CopyTo(Args, args.Length);
    }

    public string[] Analysis(string text) {
      List<string> list = new List<string>();
      int pointer = 0;
      const char SPACE = ' ';
      const char QUOTE = '"';
      while (true) {
        int nextSpace = text.IndexOf(SPACE, pointer);
        if (nextSpace == -1) {
          // 当引号引用的项目是最后一个参数的时候，不会触发Quote的处理。
          // 所以需要在这个时候将引号去掉。
          list.Add(text.Substring(pointer).Replace("\"", "").Trim());
          break;
        }

        int nextQuote = text.IndexOf(QUOTE, pointer);
        // 当引号在下一个空格之中，表示下一个项目是被引号引起来的，需要分析引号
        if (nextQuote != -1 && nextQuote < nextSpace) {
          int endQuote = text.IndexOf(QUOTE, nextQuote + 1);
          string quote = text.Substring(nextQuote + 1, endQuote - nextQuote - 1);
          pointer = endQuote + 1;
          list.Add(quote);
          continue;
        }

        list.Add(text.Substring(pointer, nextSpace - pointer));
        pointer = nextSpace + 1;
      }

      return list.ToArray();
    }

    public void SetArgs(string[] args) {
      Args = args;
      if (Args == null || Args.Length == 0) {
        //Args = new string[] {"-fastren", "-t", "1", "-d", @"C:\TEMP\[Name]" };
        Args = new string[] { "-command", "-d", ConfigReader.Instance.DefaultDirectory };
        //Args = Kit.EMPTY_LIST;
      }
    }

    public override string ToString() {
      StringBuilder sb = new StringBuilder(1024);
      foreach (var i in Args) {
        sb.Append(i);
        sb.Append(" ");
      }
      return sb.ToString();
    }

    public bool IsContain(string text) {
      int currentIndex = 0;
      foreach (var i in Args) {
        if (Kit.IsEqual(i.Trim(), text)) {
          // 当检查到这个参数存在，要检查他是否配置了否定内容。
          // 当这个参数如果跟了内部参数，如果设置成了false，或者是0，则表示为false
          if (currentIndex + 1 >= Args.Length) {
            return true;
          }
          var next = Args[currentIndex + 1].ToLower().Trim();
          if (next.IndexOf("-") == 0) { // 这表示他的下一个是一个参数，而不是一个值
            return true;
          }
          // 检查否定参数
          if (Kit.IsEqual(next, "0") || Kit.IsEqual(next, "false")) {
            return false;
          }


          return true;
        }
        currentIndex++;
      }
      return false;
    }

    public int GetInteger(string key, int defaultValue = 0) {
      var str = GetParameter(key);
      if (str.Length == 0) { return defaultValue; }
      return int.TryParse(str, out int value) ? value : defaultValue;
    }

    public float GetFloat(string key, float defaultValue = 0f) {
      var str = GetParameter(key);
      if (str.Length == 0) { return defaultValue; }
      return float.TryParse(str, out float value) ? value : defaultValue;
    }

    public string GetParameter(string key, string defaultValue = Kit.EMPTY) {
      try {
        for (int i = 0; i < Args.Length; i++) {
          if (Kit.IsEqual(key, Args[i])) { // 当前的项目为Key的话，下一个参数必然是数值
            if (Args.Length <= i + 1) {
              return defaultValue;
            }
            var next = Args[i + 1];
            // 如果此参数是以“-”开头，表示他是一个Key，不是参数。返回NULL
            if (next.IndexOf("-") == 0) {
              return defaultValue;
            }

            return next;
          }
        }
      } catch (Exception) {

      }
      return defaultValue;
    }

  }
}
